home *** CD-ROM | disk | FTP | other *** search
- /*
- % INV-VFFT . C
- %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- This software is copyright (C) by the Lawrence Berkeley Laboratory.
- Permission is granted to reproduce this software for non-commercial
- purposes provided that this notice is left intact.
-
- It is acknowledged that the U.S. Government has rights to this software
- under Contract DE-AC03-765F00098 between the U.S. Department of Energy
- and the University of California.
-
- This software is provided as a professional and academic contribution
- for joint exchange. Thus, it is experimental, and is provided ``as is'',
- with no warranties of any kind whatsoever, no support, no promise of
- updates, or printed documentation. By using this software, you
- acknowledge that the Lawrence Berkeley Laboratory and Regents of the
- University of California shall have no liability with respect to the
- infringement of other copyrights by any part of this software.
-
- For further information about this notice, contact William Johnston,
- Bld. 50B, Rm. 2239, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
- (wejohnston@lbl.gov)
-
- For further information about this software, contact:
- Jin Guojun
- Bld. 50B, Rm. 2275, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
- g_jin@lbl.gov
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Inverse Virtual Fast Fourier Transform
- %
- % Only one write_header() between header processing and inv_vfft.
- %
- % AUTHOR: Jin Guojun - LBL 5/10/91
- */
- char usage[]="options\n\
- -B output BYTE format. Default is float.\n\
- -D 2D test \n\
- -cut cut both ends and output BYTE image\n\
- [<] VFFT [> Image]\n";
-
- #include "complex.h"
- #include "header.def"
- #include "imagedef.h"
-
- U_IMAGE uimg;
-
- bool cut;
- MType dimen1len, dimen2size, fsize, vsize;
-
- #define row uimg.height
- #define cln uimg.width
- #define frm uimg.frames
-
-
- main(argc, argv)
- int argc;
- char* argv[];
- {
- bool dimens=0, vflag;
- int i, j, f, hrows, hcols, logfrms, logrows, logcols;
-
- format_init(&uimg, IMAGE_INIT_TYPE, HIPS, -1, *argv, "S20-1");
- uimg.o_form = IFMT_FLOAT;
-
- for (i=1;i<argc;i++) {
- if (argv[i][0] == '-'){
- switch(argv[i][1]) {
- case 'c': cut++;
- case 'B': uimg.o_form = IFMT_BYTE;
- break;
- case 'D': dimens++;
- break;
- default:
- info: usage_n_options(usage, i, argv[i]);
- }
- }
- else if (freopen(argv[i], "r", stdin) == NULL)
- syserr("can't open %s as input", argv[i]);
- }
-
- io_test(stdin_fd, goto info);
-
- (*uimg.header_handle)(HEADER_READ, &uimg, 0, 0);
-
- vflag = uimg.in_form==IFMT_DVVFFT3D || uimg.in_form==IFMT_VVFFT3D;
- if (uimg.o_form==IFMT_BYTE)
- uimg.pxl_out = 1;
- else uimg.pxl_out = 4;
-
- hrows = row >> 1;
- hcols = cln >> 1;
- dimen1len = hcols+1;
- vsize = row * dimen1len;
- fsize = row * cln;
- if (!vflag) /* vvfft must be in 3D. */
- dimens |= !(uimg.in_form & 1);
-
- logfrms=logrows=logcols = -1;
- for (i=0,j=1;i<12;i++,j+=j) {
- if (j==row) logrows=i;
- if (j==cln) logcols=i;
- if (j==frm) logfrms=i;
- }
-
- (*uimg.header_handle)(HEADER_WRITE, &uimg, argc, argv, True);
-
- if (logfrms<0 || logrows<0 || logcols<0){
- mesg("not power of 2, be patient for slow processing\n");
-
- # include "inrlvfft.cxx"
- exit(0);
- }
-
- w_init(MAX(MAX(hrows, hcols), 1<<logfrms-1));
-
- if (uimg.in_form==IFMT_DVFFT3D || uimg.in_form==IFMT_DVFFT2D){
- double *temp, *re_i, *im_i, *cvt,
- *re_o = (double*)nzalloc(fsize, sizeof(double)<<1, "ibuf"),
- *im_o = re_o + fsize;
-
- if (!dimens){
- re_i = (double*)nzalloc(frm*vsize, sizeof(double)<<1, "obuf");
- im_i = re_i + frm*vsize;
- cvt = re_o;
- }
- else cvt = (double*)nzalloc(fsize, sizeof(*cvt)<<1, "cvt");
-
- if (!dimens){
- w_load(1<<logfrms);
- if (vflag){
- for (f=0; f<frm; f++){
- upread(re_i+f*vsize, sizeof(*re_i), vsize, stdin);
- upread(im_i+f*vsize, sizeof(*im_i), vsize, stdin);
- }
- for (i=frm*vsize; i--;)
- im_i[i] = -im_i[i];
- }
- else {
- register double *fop,
- *re_c = re_i,
- *im_c = im_i;
- for (f=0; f<frm; f++){
- fop = cvt;
- i = upread(fop, sizeof(*fop)<<1, vsize, stdin);
- if (i != vsize)
- syserr("f%d [%d] read %d", f, vsize, i);
- for (i=vsize; i--;){
- *re_c++ = *fop++;
- *im_c++ = -*fop++;
- }
- }
- }
- for (i=0; i<vsize; i++)
- dvfftn(re_i+i, im_i+i, logfrms, vsize);
- }
-
- for (f=0; f<frm; f++){
- if (dimens){
- register double *re_out = re_o, *im_out = im_o;
- temp = cvt;
- upread(temp, sizeof(*temp)<<1, vsize, stdin);
- for (i=0; i<row; i++){
- for (j=0; j<dimen1len; j++){
- *re_out++ = *temp++;
- *im_out++ = -*temp++;
- }
- re_out += cln - dimen1len;
- im_out += cln - dimen1len;
- }
- }
- else {
- register double *re_c = re_i + f*vsize,
- *im_c = im_i + f*vsize,
- *re_out = re_o, *im_out = im_o;
- for (i=0; i<row; i++){
- for (j=0; j<dimen1len; j++){
- *re_out++ = *re_c++; /* if nothing re_c */
- *im_out++ = *im_c++; /* will be 100 times fast */
- }
- re_out += hcols-1;
- im_out += hcols-1;
- }
- }
- dvrft_2d(re_o, im_o, logrows, logcols);
-
- if (uimg.o_form == IFMT_BYTE){
- dtob(re_o, im_o, fsize, 1./((double)fsize*(uimg.in_form&1?frm:1)));
- temp = im_o;
- }
- else
- {
- register double total = 1. / (fsize*(uimg.in_form&1?frm:1));
- register float *op = (float*)(temp = re_o);
- for (i=0; i<fsize; i++)
- op[i] = temp[i] * total;
- }
- fwrite(temp, uimg.pxl_out, fsize, out_fp);
- }
- }
- else {
- float *temp, *re_i, *im_i, *cvt,
- *re_o = (float*)nzalloc(fsize, sizeof(float)<<1, "ibuf"),
- *im_o = re_o + fsize;
-
- if (!dimens){
- re_i = (float*)nzalloc(frm*vsize, sizeof(float)<<1, "obuf");
- im_i = re_i + frm*vsize;
- cvt = re_o;
- }
- else cvt = (float*)nzalloc(fsize, sizeof(*cvt)<<1, "cvt");
-
- if (!dimens){
- w_load(1<<logfrms);
- if (vflag){
- for (f=0; f<frm; f++){
- upread(re_i+f*vsize, sizeof(*re_i), vsize, stdin);
- upread(im_i+f*vsize, sizeof(*im_i), vsize, stdin);
- }
- for (i=frm*vsize; i--;)
- im_i[i] = -im_i[i];
- }
- else {
- register float *fop,
- *re_c = re_i,
- *im_c = im_i;
- for (f=0; f<frm; f++){
- fop = cvt;
- i = upread(fop, sizeof(*fop)<<1, vsize, stdin);
- if (i != vsize)
- syserr("f%d [%d] read %d", f, vsize<<3, i);
- for (i=vsize; i--;){
- *re_c++ = *fop++;
- *im_c++ = -*fop++;
- }
- }
- }
- for (i=0; i<vsize; i++)
- vfftn(re_i+i, im_i+i, logfrms, vsize);
- }
-
- for (f=0; f<frm; f++){
- if (dimens){
- register float *re_out = re_o, *im_out = im_o;
- temp = cvt;
- upread(temp, sizeof(*temp)<<1, vsize, stdin);
- for (i=0; i<row; i++){
- for (j=0; j<dimen1len; j++){
- *re_out++ = *temp++;
- *im_out++ = -*temp++;
- }
- re_out += cln - dimen1len;
- im_out += cln - dimen1len;
- }
- }
- else {
- register float *re_c = re_i + f*vsize,
- *im_c = im_i + f*vsize,
- *re_out = re_o, *im_out = im_o;
- for (i=0; i<row; i++){
- for (j=0; j<dimen1len; j++){
- *re_out++ = *re_c++; /* if nothing re_c */
- *im_out++ = *im_c++; /* will be 100 times fast */
- }
- re_out += hcols-1;
- im_out += hcols-1;
- }
- }
- vrft_2d(re_o, im_o, logrows, logcols);
-
- if (uimg.o_form == IFMT_BYTE){
- ftob(re_o, im_o, fsize, 1./(fsize*(uimg.in_form&1?frm:1)));
- temp = im_o;
- }
- else
- {
- register float total = 1. / (fsize*(uimg.in_form&1?frm:1));
- temp = re_o;
- for (i=0; i<fsize; i++)
- temp[i] *= total;
- }
- fwrite(temp, uimg.pxl_out, fsize, out_fp);
- }
- }
- }
-
- ftob(ibp, obp, n, scale)
- register float* ibp;
- register byte *obp;
- register int n;
- register float scale;
- {
- #ifdef _DEBUG_
- message("%d FtoB, scale=%f\n", n, scale);
- #endif
- if (cut) while (n--)
- *obp++ = *ibp++ * scale;
- else for (;n--; obp++) {
- register int tmp = *ibp++ * scale;
- if (tmp < 0)
- *obp = 0;
- else if (tmp>255)
- *obp = 255;
- else *obp = tmp;
- }
- }
-
- dtob(ibp, obp, n, scale)
- register double *ibp;
- register byte *obp;
- register int n;
- register double scale;
- {
- register int tmp;
-
- #ifdef _DEBUG_
- message("%d DtoB, scale=%lf\n", n, scale);
- #endif
- for (; n--; obp++) {
- tmp = *ibp++ * scale;
- if (tmp < 0)
- *obp = 0;
- else if (tmp>255)
- *obp = 255;
- else *obp = tmp;
- }
- }
-
- dtof(ibp, obp, n, scale) /* for non power of 2 processing */
- register double *ibp;
- register float *obp;
- register int n;
- register double scale;
- {
- #ifdef _DEBUG_
- message("%d DtoF, scale=%lf\n", n, scale);
- #endif
- while (n--)
- *obp++ = *ibp++ * scale;
- }
-